/**
 * 
 */
package com.isoftstone.storage;

import java.io.File;
import java.util.List;

import com.isoftstone.storage.authentication.AuthenticationException;
import com.isoftstone.storage.authentication.AuthenticationInfo;
import com.isoftstone.storage.authorization.AuthorizationException;
import com.isoftstone.storage.events.SessionListener;
import com.isoftstone.storage.events.TransferListener;
import com.isoftstone.storage.repository.Repository;

/**
 * 存储层接口
 * 
 */
public interface Storage {
	/**
	 * 缺省连接超时，60秒
	 */
	public static final int DEFAULT_CONNECTION_TIMEOUT = 60000;

	/**
	 * 缺省读超时，30分钟
	 * 
	 */
	public static final int DEFAULT_READ_TIMEOUT = 1800000;

	// ----------------------------------------------------------------------
	// 文件/文件处理
	// ----------------------------------------------------------------------

	/**
	 * * 从仓库下载远程资源到本地文件
	 * 
	 * @param resourceName
	 *            远程资源名
	 * @param destination
	 *            本地文件
	 * @throws TransferFailedException
	 *             如果发生传输错误
	 * @throws ResourceDoesNotExistException
	 *             如果资源不存在
	 * @throws AuthorizationException
	 *             如果发生授权失败
	 */
	void get(String resourceName, File destination)
			throws TransferFailedException, ResourceDoesNotExistException,
			AuthorizationException;

	/**
	 * 复制本地文件到仓库目标
	 * 
	 * @param source
	 *            本地文件
	 * @param destination
	 *            远程目标
	 * @return 返回值由具体实现来决定，FileStorage返回描述远程文件路径的字符串；FastDfsStorage返回长度为2的字符串数组,
	 *         元素0为FastDFS的group_name,元素1为remoteFilename
	 * 
	 * @throws TransferFailedException
	 *             如果发生传输错误
	 * @throws ResourceDoesNotExistException
	 *             如果资源不存在
	 * @throws AuthorizationException
	 *             如果发生授权失败
	 */
	Object put(File source, String destination) throws TransferFailedException,
			ResourceDoesNotExistException, AuthorizationException;

	/**
	 * 删除远程资源。
	 * 
	 * @param resourceName
	 *            远程资源名
	 * @return 当且仅当此远程资源存在时，返回 true；否则返回 false
	 * 
	 * @throws TransferFailedException
	 *             如果远程发生访问错误
	 * @throws AuthorizationException
	 *             如果未授权
	 */
	void delete(String resourceName) throws TransferFailedException,
			AuthorizationException;

	/**
	 * 测试远程资源是否存在。
	 * 
	 * @param resourceName
	 *            远程资源名
	 * @return 当且仅当此远程资源存在时，返回 true；否则返回 false
	 * 
	 * @throws TransferFailedException
	 *             如果远程发生访问错误
	 * @throws AuthorizationException
	 *             如果未授权
	 */
	boolean resourceExists(String resourceName) throws TransferFailedException,
			AuthorizationException;

	/**
	 * <p>
	 * 返回 指定此抽象路径下的文件和目录名。
	 * </p>
	 * 
	 * <p>
	 * 如果此抽象路径名不表示一个目录或不存在，此方法抛出{@link ResourceDoesNotExistException}.
	 * 否则返回一个字符串数组，每个数组元素对应目录中的每个文件或目录。
	 * </p>
	 * <p>
	 * 不保证所得数组中的相同字符串将以特定顺序出现，特别是不保证它们按字母顺序出现。
	 * </p>
	 * 
	 * @param destinationDirectory
	 *            directory to list contents of
	 * @return 字符串数组{@link List}
	 *         ，这些字符串指定此路径名表示的目录中的文件和目录。如果目录为空，那么数组也将为空。如果此路径名不表示一个目录，或者发生 I/O
	 *         错误，则返回 null。
	 * 
	 * @throws TransferFailedException
	 *             如果远程发生访问错误
	 * @throws ResourceDoesNotExistException
	 *             如果指定目录不存在或不是一个目录
	 * @throws AuthorizationException
	 *             如果未授权
	 */
	List<String> getFileList(String destinationDirectory)
			throws TransferFailedException, ResourceDoesNotExistException,
			AuthorizationException;

	/**
	 * 标识此storage是否支持目录复制
	 * 
	 * @return 当且仅当此storage支持目录操作时，返回 true；否则返回 false
	 */
	boolean supportsDirectoryCopy();

	/**
	 * 获取仓库信息
	 * 
	 * @return 返回当前仓库对象
	 */
	Repository getRepository();

	// ----------------------------------------------------------------------
	// 连接/断开连接
	// ----------------------------------------------------------------------

	/**
	 * 连接到仓库
	 * 
	 * @param source
	 *            连接仓库
	 * @throws ConnectionException
	 *             如果发生连接问题
	 * @throws AuthenticationException
	 *             如果连接进使用的身份不够
	 */
	void connect(Repository source) throws ConnectionException,
			AuthenticationException;

	/**
	 * 连接到仓库
	 * 
	 * @param source
	 *            连接仓库
	 * @param authenticationInfo
	 *            用于连接的身份信息
	 * @throws ConnectionException
	 *             如果发生连接问题
	 * @throws AuthenticationException
	 *             如果连接进使用的身份不够
	 */
	void connect(Repository source, AuthenticationInfo authenticationInfo)
			throws ConnectionException, AuthenticationException;

	/**
	 * 断开连接 from the repository.
	 * 
	 * @throws ConnectionException
	 *             如果断开连接时发生问题
	 */
	void disconnect() throws ConnectionException;

	/**
	 * 设置连接超时，以毫秒为单位
	 */
	void setTimeout(int timeoutValue);

	/**
	 * 获取连接超时，以毫秒为单位
	 */
	int getTimeout();

	/**
	 * 设置读取超时，以毫秒为单位
	 */
	void setReadTimeout(int timeoutValue);

	/**
	 * 获取读取超时，以毫秒为单位
	 */
	int getReadTimeout();

	// ----------------------------------------------------------------------
	// 会话监听器
	// ----------------------------------------------------------------------

	void addSessionListener(SessionListener listener);

	void removeSessionListener(SessionListener listener);

	boolean hasSessionListener(SessionListener listener);

	// ----------------------------------------------------------------------
	// 传输监听器
	// ----------------------------------------------------------------------

	void addTransferListener(TransferListener listener);

	void removeTransferListener(TransferListener listener);

	boolean hasTransferListener(TransferListener listener);

	boolean isInteractive();

	void setInteractive(boolean interactive);

}
